'use strict'

const Service = require('egg').Service

class RoleService extends Service {


    /**
     * 查询接口service
     * @param offset
     * @param limit
     * @param search
     * @param isPage
     * @returns {Promise<*>}
     */
    async index(offset = 0,limit = 10,search = '%%',isPage = 'true'){
        const {app,ctx,service} = this;
        //sequelize的复杂运算符参数
        const Op = app.Sequelize.Op;
        //定义查询参数
        let param = {
            where:{
                name:{
                    [Op.like]:`%${search}%`
                },
                deleted:'0'
            },
            order:[['created_at','desc']]
        };
        //判断是否分页
        if(isPage == 'true'){
            param.offset = offset;
            param.limit = limit;
        }else{
            let redis_data = await app.sessionStore.get('role_list');
            if(!app.lodash.isEmpty(redis_data)){
                return redis_data;
            }
        }
        //调用sequelize查询数据库
        let data = await ctx.model.FdRole.findAndCountAll(param);

        //redis缓存
        //判断是否分页 只缓存不分页的查询
        if(isPage != 'true'){
            await app.sessionStore.set('role_list',data);
        }

        //返回结果
        return data;
    }

    /**
     * 新建接口service
     * @param param
     * @returns {Promise<*>}
     */
    async create(param){
        const {app,ctx,service} = this;
        //引入uuid生成器
        var uuid = require('node-uuid');

        //开启事务
        let t = await ctx.model.transaction();
        try {
            //定义新增的对象
            let role = {
                id:uuid.v1(),
                name:param.name,
                code:param.code,
                deleted: '0'
            };
            //调用sequelize新增对象 findOrCreate 将返回一个数组[对象，新增成功与否的布尔] 如果新增对象已存在，则返回该对象和false 否则返回新增对象和true
            let rs = await ctx.model.FdRole.findOrCreate({where:{code:role.code},defaults:role,transaction:t});

            //读取权限数组
            let auth = param.auth;

            //若对象添加成功 则添加 对象与权限的对应关系
            let redis_temp_auths = [];
            if(rs[1]){
                if(!app.lodash.isEmpty(auth)){
                    //遍历权限数组
                    for(let i = 0 ,len = auth.length;i < len;i++){
                        //初始化
                        let role_auth = {
                            id:uuid.v1(),
                            role_id:rs[0].id,
                            auth_id:auth[i]
                        }
                        let redis_temp_auth = {
                            id:role_auth.auth_id
                        }
                        redis_temp_auths.push(redis_temp_auth);
                        //新增
                        let res = await ctx.model.FdRoleAuth.findOrCreate({where:{role_id: role_auth.role_id,auth_id:role_auth.auth_id,deleted:'0'},defaults: role_auth,transaction:t});
                    }
                }
            }

            //提交事务
            await t.commit();

            //清空此模块的redis缓存
            app.sessionStore.destroy('role_list');

            //新增此对象的redis缓存
            app.sessionStore.set('role_'+role.id,[rs[0],redis_temp_auths]);

            //返回新增结果
            return rs[1];

        }catch (e) {
            //若出错 回滚
            await t.rollback();
            //抛出出错信息
            ctx.throw(500,e.message)
        }
    }

    /**
     * 删除接口service
     * @param param
     * @returns {Promise<boolean>}
     */
    async destroy(param){
        const {app,ctx,service} = this;
        //开启事务
        let t = await ctx.model.transaction();
        try {
            //更新要删除对象的deleted字段为1 采取逻辑删除
            let rs = await ctx.model.FdRole.update({deleted:'1'},{where:{id:param.id},transaction:t});
            //rs返回影响的数据行数

            //提交事务
            t.commit();

            //清空此模块的redis缓存
            app.sessionStore.destroy('role_list');

            //清空此id的redis缓存
            app.sessionStore.destroy('role_'+param.id);

            //判断删除结果 若成功，则为1
            if(rs[0] === 1){
                return true;
            }else{
                return false;
            }

        }catch (e) {
            //失败 回滚
            t.rollback();
            //抛出错误信息
            ctx.throw(500,e.message)
        }
    }

    /**
     * 单一数据查询接口service
     * @param param
     * @returns {Promise<*>}
     */
    async show(param){
        const {app,ctx,service} = this;
        //调用sequelize查询 findOne 只返回查询接口的第一个
        let redis_auth = await app.sessionStore.get('role_'+param.id);
        if(!app.lodash.isEmpty(redis_auth)){
            return redis_auth;
        }
        let role = await ctx.model.FdRole.findOne({where:{id:param.id,deleted:'0'},attributes:['id','name','code']});
        let auth = await ctx.model.FdRoleAuth.findAll({where:{role_id:param.id,deleted:"0"},attributes: [['auth_id','id']]});

        await app.sessionStore.set('role_'+param.id,[role,auth]);

        return [role,auth];
    }

    /**
     * 更新接口service
     * @param param
     * @returns {Promise<boolean>}
     */
    async update(param){
        const {app,ctx,service} = this;
        //引入uuid生成器
        var uuid = require('node-uuid');

        //开启事务
        let t = await ctx.model.transaction();
        try {
            let role = {
                id:param.id,
                name:param.name,
                code:param.code
            }
            //调用sequelize update更新为批量更新 只要满足where条件的数据都将被更新
            let rs = await ctx.model.FdRole.update(role,{where:{id:param.id},transaction:t});
            //先清空对应关系 再重新添加对应关系
            let rs1 = await ctx.model.FdRoleAuth.destroy({where:{role_id:param.id},transaction:t});
            let auth = param.auth;
            if(!app.lodash.isEmpty(auth)){
                //遍历权限数组
                for(let i = 0 ,len = auth.length;i < len;i++){
                    //初始化
                    let role_auth = {
                        id:uuid.v1(),
                        role_id:param.id,
                        auth_id:auth[i]
                    }
                    //新增
                    let res = await ctx.model.FdRoleAuth.findOrCreate({where:{role_id: role_auth.role_id,auth_id:role_auth.auth_id,deleted:'0'},defaults: role_auth,transaction:t});
                }
            }

            //rs返回影响的数据行数

            //提交事务
            t.commit();

            //清空此模块的redis缓存
            app.sessionStore.destroy('role_list');

            //删除此id的redis缓存
            app.sessionStore.destroy('role_'+param.id);

            //判断结果
            if(rs[0] === 1){
                return true;
            }else{
                return false;
            }

        }catch (e) {
            //失败回滚
            t.rollback();
            //抛出错误信息
            ctx.throw(500,e.message)
        }
    }
}

module.exports = RoleService
